clear; clc; close all;
dataset = 'movielen1m';
load(strcat('../noncvx-lowrank/data/recsys/', dataset, '.mat'));
% load('matlab.mat');

[row, col, val] = find(data);
idx = randperm(length(val));

val = val - mean(val);
val = val/std(val);

traIdx = idx(1:floor(length(val)*0.5));
tstIdx = idx(ceil(length(val)*0.5): end);

clear idx;

traData = sparse(row(traIdx), col(traIdx), val(traIdx));
traData(size(data,1), size(data,2)) = 0;

para.maxIter = 5000;
para.decay = 0.8;

% data split
% gridLambda = 40*(0.9).^(1:11);
% para.tol = 1e-2;
% para.exact = 0;
% 
% for g = 1:length(gridLambda)
%     lambda = gridLambda(g);
%     para.maxR = 40 + 10*g;
%     
%     [U, S, V] = AccSoftImpute(traData', lambda, para );
%     
%     RMSE(g) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx))
% end
% clear U S V g;

para.test.row  = row(tstIdx);
para.test.col  = col(tstIdx);
para.test.data = val(tstIdx);

%% start testing
switch (dataset)
    case 'movielen100k'
        lambda = 8.5;
        para.tol = 1e-3;
        
        para.maxR = 100;
    case 'movielen1m'
        lambda = 18.5;
        para.tol = 1e-2;
        
        para.exact = 1;
        para.maxR = 200;
    case 'movielen10m'
        lambda = 45;
        
        para.tol = 1e-1;
        para.maxR = 300;
end

%% ---------------------------------------------------------------
% method = 1;
% t = tic;
% [U, S, V, out{method}] = ActiveSubspace(traData', lambda, para );
% % [U, S, V, out{1}]=mc_alt(traData', lambda, para);
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% hold on;
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));
% hold on;

%% ---------------------------------------------------------------
% method = 2;
% t = tic;
% [U, S, V, out{method}] = Boost( traData', lambda, para);
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));

%% ---------------------------------------------------------------
% method = 4;
% t = tic;
% para.decay = 0.95;
% [U, S, V, out{method}] = SoftImputeALS( traData', lambda, para.maxR, para );
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));

%% ---------------------------------------------------------------
method = 5;
t = tic;
para.exact = 0;
para.decay = 0.85;
[U, S, V, out{method}] = AccSoftImpute( traData', lambda, para );
Time(method) = toc(t);
RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
clear U S V t;

figure(1);
plot(out{method}.Time, out{method}.RMSE);
figure(2);
semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));
  
%% ---------------------------------------------------------------
% method = 6;
% t = tic;
% para.exact = 1;
% para.decay = 0.975;
% [U, S, V, out{method}] = SoftImpute( traData', lambda, para );
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));

%% ---------------------------------------------------------------
% method = 7;
% t = tic;
% para.decay = 0.85;
% [U, S, V, out{method}] = APGMatComp( traData', lambda, para );
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));

%% ---------------------------------------------------------------
% method = 3;
% t = tic;
% [U, S, V, out{method}] = MMBS(traData', lambda, para );
% Time(method) = toc(t);
% RMSE(method) = MatCompRMSE(V, U, S, row(tstIdx), col(tstIdx), val(tstIdx));
% clear U S V t;
% 
% figure(1);
% plot(out{method}.Time, out{method}.RMSE);
% figure(2);
% semilogy(out{method}.Time, out{method}.obj - min(out{method}.obj));
% 
% clear row col val traIdx tstIdx traData data user item obj P t method Age;
% 
% save(strcat(dataset, '-2'));